import { computed, Ref,ref } from "vue";
import _ from 'lodash'
import { EnumUserActionType, EnumOpType} from "@renderer/assets/types";
import type { opMsgType } from "@renderer/assets/types";
import {sendSocketIoMsg} from '@renderer/api/request'
import { getActiveTabViewOp } from "@renderer/view/hooks/common";
const ScaleFactor = 0.005

export const useHandlerTouchOrMouseOp = (rect: Ref,  hasImg) => {
  const isMouseDown = ref(false)
  const {
    activeViewRef: activeView,
    activeOpObjRef
  } = getActiveTabViewOp()

  const operationType = computed(() => {
    if (activeOpObjRef.value?.activeOp){
      return activeOpObjRef.value?.activeOp
    }else {
      return  null
    }
  });

  let currentScale = 1
  const preMoveStartPosition = {
    x: 0,
    y: 0,
    scale: 1,
    isRecord: false
  }



  let currentActionType: EnumUserActionType = EnumUserActionType.none

  const handleMousedown = (e) => {
    console.log('mousedown')
    handleDown(e)
  }
  const handleTouchStart = (e) => {
    console.log('touchstart')
    handleDown(e)
  }
  const handleDown = (e) => {
    if (!hasImg.value){
      return;
    }
    isMouseDown.value = true
    currentActionType = EnumUserActionType.down

    const { x, y } = getPosition(e)
    if (!preMoveStartPosition.isRecord) {
      preMoveStartPosition.x = x
      preMoveStartPosition.y = y
      preMoveStartPosition.isRecord = true
    }

    if (operationType.value?.type !== EnumOpType.measure) {
      return
    }

    const msg: opMsgType = {
      viewType: activeView.value.viewType,
      opType: operationType.value.type,
      subOpType: operationType.value.subType,
      actionType: currentActionType,
      x,
      y
    }
    sendSocketIoMsg(msg)
  }

  const handleMousemove = (e: MouseEvent) => {
    handleMove(e)
  }

  const handleTouchmove = (e: TouchEvent) => {
    handleMove(e)
  }
  // let rafId: any = null;
  // const handleMove = (e: MouseEvent | TouchEvent) => {
  //   if (!hasImg.value) return;
  //
  //   if (rafId) {
  //     cancelAnimationFrame(rafId);
  //   }
  //
  //   rafId = requestAnimationFrame(() => {
  //     if (isMouseDown.value) {
  //       currentActionType = EnumUserActionType.drag;
  //       updateDrag(e);
  //     } else {
  //       updateMove(e);
  //     }
  //     rafId = null;
  //   });
  // };

  const handleMove = _.throttle((e: MouseEvent | TouchEvent) => {
    if (!hasImg.value){
      return;
    }
    if (isMouseDown.value) {
      currentActionType = EnumUserActionType.drag
      updateDrag(e)
    } else {
      updateMove(e)
    }
  },30, {
    trailing: true,
  })


  const updateMove = (e) => {
    const { x, y } = getPosition(e)
    // todo 暂时关闭
    // const msg: opMsgType = {
    //   viewType: viewType,
    //   opType: 'getPosition',
    //   x,
    //   y
    // }
    // sendSocketIoMsg(msg)
  }

  const updateDrag = (e) => {
    if (operationType.value === null){
      return;
    }
    const { x, y } = getPosition(e)

    switch (operationType.value.type) {
      case EnumOpType.window:
        handleWindowOp(x, y)
        break
      case EnumOpType.pan:
        handlePanOp(x, y)
        break
      case EnumOpType.zoom:
        handleScaleOp(x, y)
        break
      case EnumOpType.scroll:
        handleScrollOp(x, y)
        break
      case EnumOpType.measure:
        handleDrawOp(e)
        break
      case EnumOpType.rotate3D:
        handleRotateOp(x, y)
        break
      default:
        break
    }
  }

  const recordPreData = (map: Object) => {
    Object.assign(preMoveStartPosition, map)
  }

  const handleWindowOp = (x, y) => {
    const directionX = x - preMoveStartPosition.x
    const directionY = y - preMoveStartPosition.y
    recordPreData({
      x: x,
      y: y,
      isRecord: true
    })
    const msg: opMsgType = {
      viewType: activeView.value.viewType,
      opType: EnumOpType.window,
      x: directionX,
      y: directionY
    }
    sendSocketIoMsg(msg)
  }
  let preTime:any = null;

  const handlePanOp = (x, y) => {


    const offset_x = x - preMoveStartPosition.x
    const offset_y = y - preMoveStartPosition.y

    // 避免移动太小距离带来的累进误差。
    if ( Math.abs(offset_x) <= 1 || Math.abs(offset_y) <= 1 ) {
      return;
    }
    recordPreData({
      x: x,
      y: y,
      isRecord: true
    })
    const msg: opMsgType = {
      viewType: activeView.value.viewType,
      opType: EnumOpType.pan,
      x: offset_x,
      y: offset_y
    }
    sendSocketIoMsg(msg)
    if (!preTime){
      preTime = Date.now();
    }else {
      const currentTime = Date.now();
      console.log(`发送操作的间隔时间为：${currentTime - preTime}`)
      preTime = currentTime;
    }

  }
  const handleScaleOp = (x, y) => {
    const directionY = (preMoveStartPosition.y - y) * ScaleFactor
    recordPreData({
      y: y,
      isRecord: true
    })
    const msg: opMsgType = {
      viewType: activeView.value.viewType,
      opType: EnumOpType.zoom,
      x: x,
      y: y,
      zoom: directionY
    }
    sendSocketIoMsg(msg)
  }
  const handleScrollOp = (x, y) => {
    if (Math.abs(y - preMoveStartPosition.y) <= 5) {
      return
    }
    const directionY = y - preMoveStartPosition.y > 5 ? 1 : -1
    recordPreData({
      x: x,
      y: y,
      isRecord: true
    })
    const msg: opMsgType = {
      viewType: activeView.value.viewType,
      opType: EnumOpType.scroll,
      scroll: directionY
    }
    sendSocketIoMsg(msg)
  }

  const handleMouseup = (e) => {
    handleUp(e)
  }

  const handleTouchEnd = (e) => {
    handleUp(e)
  }

  const handleUp = (e) => {
    if (!hasImg.value){
      return;
    }
    isMouseDown.value = false
    recordPreData({
      x: 0,
      y: 0,
      scale: currentScale,
      isRecord: false
    })
    currentActionType = EnumUserActionType.up
    handleDrawOp(e)
    currentActionType = EnumUserActionType.none
  }
  const handleDrawOp = (e) => {
    const { x, y } = getPosition(e)
    if (operationType.value?.type !== EnumOpType.measure) {
      return
    }
    const msg: opMsgType = {
      viewType: activeView.value.viewType,
      opType: operationType.value.type,
      subOpType: operationType.value.subType,
      actionType: currentActionType,
      x: x,
      y: y
    }
    sendSocketIoMsg(msg)
  }

  const handleRotateOp = (x, y) => {
    if (operationType.value === null){
      return;
    }
    const deltaY = y - preMoveStartPosition.y
    const deltaX = x - preMoveStartPosition.x
    if (Math.abs(deltaX) <= 5 && Math.abs(deltaY) <= 5) {
      return
    }

    recordPreData({
      x: x,
      y: y,
      isRecord: true
    })
    const msg = {
      viewType: activeView.value.viewType,
      opType: operationType.value?.type,
      actionType: currentActionType,
      x: Number.parseFloat((deltaX * 0.2).toFixed(2)),
      y: Number.parseFloat((deltaY * 0.2).toFixed(2))
    }
    sendSocketIoMsg(msg)
  }

  const getPosition = (e: MouseEvent | TouchEvent) => {
    if (e instanceof MouseEvent) {
      const xVal = e.clientX - rect.value.left
      const yVal = e.clientY - rect.value.top
      return {
        x: xVal,
        y: yVal
      }
    } else {
      if (e.targetTouches && e.targetTouches.length > 0) {
        return {
          x: e.targetTouches[0].clientX - rect.value.left,
          y: e.targetTouches[0].clientY - rect.value.top
        }
      } else {
        return {
          x: e.changedTouches[0].clientX - rect.value.left,
          y: e.changedTouches[0].clientY - rect.value.top
        }
      }
    }
  }

  const handleWheel = (e: any) => {
    if (!hasImg.value){
      return;
    }
    const msg: opMsgType = {
      viewType: activeView.value.viewType,
      opType: EnumOpType.scroll,
      scroll: e.deltaY > 0 ? 1 : -1
    }
    sendSocketIoMsg(msg)
  }
  return {
    handleMousedown,
    handleMousemove,
    handleMouseup,

    handleTouchStart,
    handleTouchEnd,
    handleTouchmove,
    handleWheel,
    isMouseDown,
  }
}
